#include "jsgauge.h"
#include "websocketclientwrapper.h"
#include "websockettransport.h"
#include "translator.h"

#include <QFile>
#include <QApplication>
#include <QDebug>

class JsGaugePrivate
{
public:
    JsGaugePrivate(JsGauge* q);

    JsGauge* q_ptr;
    QWebEnginePage* page = nullptr;
    Translator* translator = nullptr;
    int value = 0;

    void createTranslator();
    void createPage();
};

JsGaugePrivate::JsGaugePrivate(JsGauge *q) : q_ptr(q)
{

}

void JsGaugePrivate::createTranslator()
{
    translator = new Translator(q_ptr);
}

void JsGaugePrivate::createPage()
{
    if (!page)
        page = new QWebEnginePage(q_ptr);

    QString html = "<script src=\"http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.js\"></script>"
                   "<script src=\"http://cdn.bootcss.com/highcharts/4.2.3/highcharts.js\"></script>"
                   "<script src=\"http://cdn.bootcss.com/highcharts/4.2.3/highcharts-more.js\"></script>"
                   "<div id=\"container\" style=\"min-width: 310px; height: 400px; margin: 0 auto\"></div>";

    QFile jsChannelFile(":./qwebchannel.js");
    if (!jsChannelFile.open(QIODevice::ReadOnly))
        qDebug() << "failed to read web channel file.";

    QString jswebchannel = "<script>" + jsChannelFile.readAll() + "</script>";
    QString commScript = "<script>window.onload = function() {"
                         "  console.log('script loaded');"
                         "if (location.search != \"\")"
                         "    var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]);"
                         "else"
                         "    var baseUrl = \"ws://localhost:12345\";"
                         "var socket = new WebSocket(baseUrl);"
                         "socket.onclose = function()"
                         "{"
                         "    console.error(\"web channel closed\");"
                         "};"
                         "socket.onerror = function(error)"
                         "{"
                         "    console.error(\"web channel error: \" + error);"
                         "};"
                         "socket.onopen = function()"
                         "{"
                         "    new QWebChannel(socket, function(channel) {"
                         "    window.translator = channel.objects.translator;"
                         "    translator.valueChanged.connect(function(value) {"
                         "          var chart = $('#container').highcharts();"
                         "          var point = chart.series[0].points[0];"
                         "          point.update(value);"
                         "})"
                         "});"
                         "}}</script>";

    QString script = "<script>$(function () {"
                      "     $('#container').highcharts({"
                      "         chart: {"
                      "             type: 'gauge',"
                      "             plotBackgroundColor: null,"
                      "             plotBackgroundImage: null,"
                      "             plotBorderWidth: 0,"
                      "             plotShadow: false"
                      "         },"
                      "         title: {"
                      "             text: 'Speedometer'"
                      "         },"
                      "         pane: {"
                      "             startAngle: -150,"
                      "             endAngle: 150,"
                      "             background: [{"
                      "                 backgroundColor: {"
                      "                     linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },"
                      "                     stops: ["
                      "                         [0, '#FFF'],"
                      "                         [1, '#333']"
                      "                     ]"
                      "                 },"
                      "                 borderWidth: 0,"
                      "                 outerRadius: '109%'"
                      "             }, {"
                      "                 backgroundColor: {"
                      "                     linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },"
                      "                     stops: ["
                      "                         [0, '#333'],"
                      "                         [1, '#FFF']"
                      "                     ]"
                      "                 },"
                      "                 borderWidth: 1,"
                      "                 outerRadius: '107%'"
                      "             }, {"
                      "             }, {"
                      "                 backgroundColor: '#DDD',"
                      "                 borderWidth: 0,"
                      "                 outerRadius: '105%',"
                      "                 innerRadius: '103%'"
                      "             }]"
                      "         },"
                      "         yAxis: {"
                      "             min: 0,"
                      "             max: 200,"
                      "             minorTickInterval: 'auto',"
                      "             minorTickWidth: 1,"
                      "             minorTickLength: 10,"
                      "             minorTickPosition: 'inside',"
                      "             minorTickColor: '#666',"
                      "             tickPixelInterval: 30,"
                      "             tickWidth: 2,"
                      "             tickPosition: 'inside',"
                      "             tickLength: 10,"
                      "             tickColor: '#666',"
                      "             labels: {"
                      "                 step: 2,"
                      "                 rotation: 'auto'"
                      "             },"
                      "             title: {"
                      "                 text: 'km/h'"
                      "             },"
                      "             plotBands: [{"
                      "                 from: 0,"
                      "                 to: 120,"
                      "                 color: '#55BF3B'"
                      "             }, {"
                      "                 from: 120,"
                      "                 to: 160,"
                      "                 color: '#DDDF0D'"
                      "             }, {"
                      "                 from: 160,"
                      "                 to: 200,"
                      "                 color: '#DF5353'"
                      "             }]"
                      "         },"
                      "         series: [{"
                      "             name: 'Speed',"
                      "             data: [80],"
                      "             tooltip: {"
                      "                 valueSuffix: 'km/h'"
                      "             }"
                      "         }]"
                      "     },"
                      "     function (chart) {"
                      "         if (!chart.renderer.forExport) {"
                      "             setInterval(function () {"
                      "                 var point = chart.series[0].points[0],"
                      "                     newVal,"
                      "                     inc = Math.round((Math.random() - 0.5) * 20);"
                      "                 newVal = point.y + inc;"
                      "                 if (newVal < 0 || newVal > 200) {"
                      "                     newVal = point.y - inc;"
                      "                 }"
                      "                 window.translator.setValue(newVal);"
                      "                 point.update(newVal);"
                      "             }, 3000);"
                      "         }"
                      "     });"
                      " });</script>";

    html += jswebchannel;
    html += commScript;
    html += script;

    page->setHtml(html);
    q_ptr->setPage(page);
}

JsGauge::JsGauge(QWidget* parent) : QWebEngineView(parent)
{
    d_ptr = new JsGaugePrivate(this);
    d_ptr->createTranslator();
    d_ptr->createPage();
}

JsGauge::~JsGauge()
{
    delete d_ptr;
}

void JsGauge::setValue(int value)
{
    if (d_ptr->value != value) {
        d_ptr->value = value;
        emit d_ptr->translator->valueChanged(value);
    }
}

int JsGauge::value() const
{
    return d_ptr->value;
}

Translator* JsGauge::translator() const
{
    return d_ptr->translator;
}
